import {
  Rule,
  ValidateFieldsError,
} from "async-validator/dist-types/interface";
import { CSSProperties, VNode } from "vue";
import { ColEx } from "../../../Table/src/types";
import { FormItem } from "../types/formItem";
import { TableActionType } from "../../../Table/src/types/table";
import { Recordable } from "/#/global";
import { FormItemProp, FormRules, RowProps } from "element-plus/es";
import { ComponentType } from ".";
import { OptionType } from "element-plus/es/components/select-v2/src/select.types";

export type RegisterFn = (formInstance: FormActionType) => void;

export type UseFormReturnType = [RegisterFn, FormActionType];

export interface FormActionType {
  // 重置字段
  resetFields: () => Promise<void>;
  validateField: (
    props?: Array<FormItemProp>,
    callback?: (isValid: boolean, invalidFields?: ValidateFieldsError) => void
  ) => Promise<void>;
  getFieldsValue: () => Recordable;
  setProps: (formProps: Partial<FormProps>) => Promise<void>;
  // scrollToField: (name: NamePath, options?: ScrollOptions) => Promise<void>;
  setFieldsValue: <T>(values: T) => Promise<void>;
  resetSchema: (
    data: Partial<FormSchema> | Partial<FormSchema>[]
  ) => Promise<void>;
  updateSchema: (
    data: Partial<FormSchema> | Partial<FormSchema>[]
  ) => Promise<void>;
  validate: (
    callback?: (isValid: boolean, invalidFields?: ValidateFieldsError) => void
  ) => Promise<any>;
}

export interface FormProps {
  // 表单数据对象
  model: Recordable;
  // 表单验证规则
  rules?: FormRules;
  // 表单域标签的位置， 当设置为 left 或 right 时，则也需要设置 label-width 属性
  labelPosition?: string;
  // 表单域标签的位置， 当设置为 left 或 right 时，则也需要设置 label-width 属性
  labelWidth?: string | number;
  // 表单域标签的后缀
  labelSuffix?: string;
  // 行内表单模式
  inline?: boolean;
  inlineMessage?: BooleanConstructor;
  // 是否在输入框中显示校验结果反馈图标
  statusIcon?: boolean;
  // 是否显示校验错误信息
  showMessage?: boolean;
  // 用于控制该表单内组件的尺寸
  size?: "large" | "default" | "small";
  // 是否禁用该表单内的所有组件。 如果设置为 true, 它将覆盖内部组件的 disabled 属性。
  disabled?: boolean;
  // 是否在 rules 属性改变后立即触发一次验证
  validateOnRuleChange?: boolean;
  // 是否显示必填字段的标签旁边的红色星号
  hideRequiredAsterisk?: boolean;
  scrollToError?: boolean;

  // 表单组件架构
  schemas?: FormSchema[];
  // Whether to show collapse and expand buttons
  showAdvancedButton?: boolean;

  // General row style
  baseRowStyle?: CSSProperties;

  // Row configuration for the entire form
  rowProps?: RowProps;
  // Function values used to merge into dynamic control form items
  mergeDynamicData?: Recordable;

  componentMinWidth?: number | string;
}

export interface RenderCallbackParams {
  schema: FormSchema;
  values: Recordable;
  model: Recordable;
  field: string;
}

export interface HelpComponentProps {
  maxWidth: string;
  // Whether to display the serial number
  showIndex: boolean;
  // Text list
  text: any;
  // colour
  color: string;
  // font size
  fontSize: string;
  icon: string;
  absolute: boolean;
  // Positioning
  position: any;
}

export interface FormSchema {
  // Field name
  field: string;
  // 对象字段的引用key
  fieldKey?: string;
  // Event name triggered by internal value change, default change
  changeEvent?: string;
  // Variable name bound to v-model Default value
  valueField?: string;
  // Label name
  label: string;
  // Auxiliary text
  subLabel?: string;
  // Help text on the right side of the text
  helpMessage?:
  | string
  | string[]
  | ((renderCallbackParams: RenderCallbackParams) => string | string[]);
  // BaseHelp component props
  helpComponentProps?: Partial<HelpComponentProps>;
  // Label width, if it is passed, the labelCol and WrapperCol configured by itemProps will be invalid
  labelWidth?: string | number;
  // Disable the adjustment of labelWidth with global settings of formModel, and manually set labelCol and wrapperCol by yourself
  disabledLabelWidth?: boolean;
  // render component
  component: ComponentType;
  // Component parameters
  componentProps?:
  | ((opt: {
    schema: FormSchema;
    tableAction: TableActionType;
    formActionType: FormActionType;
    formModel: Recordable;
  }) => Recordable)
  | object;
  // Required
  required?:
  | boolean
  | ((renderCallbackParams: RenderCallbackParams) => boolean);

  suffix?:
  | string
  | number
  | ((values: RenderCallbackParams) => string | number);

  // Validation rules
  rules?: Rule[];
  // Check whether the information is added to the label
  rulesMessageJoinLabel?: boolean;

  // Reference formModelItem
  itemProps?: Partial<FormItem>;

  // col configuration outside formModelItem
  colProps?: Partial<ColEx>;

  // 默认值
  defaultValue?: any;
  isAdvanced?: boolean;

  // Matching details components
  span?: number;

  ifShow?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);

  show?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);

  // Render the content in the form-item tag
  render?: (
    renderCallbackParams: RenderCallbackParams
  ) => VNode | VNode[] | string;

  // Rendering col content requires outer wrapper form-item
  renderColContent?: (
    renderCallbackParams: RenderCallbackParams
  ) => VNode | VNode[] | string;

  renderComponentContent?:
  | ((renderCallbackParams: RenderCallbackParams) => any)
  | VNode
  | VNode[]
  | string;

  // Custom slot, in from-item
  slot?: string;

  // 组件插槽
  slots?: VNode | {}

  // Custom slot, similar to renderColContent
  colSlot?: string;

  dynamicDisabled?:
  | boolean
  | ((renderCallbackParams: RenderCallbackParams) => boolean);

  dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[];
}
